package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.*;
import com.tanhua.dubbo.utils.IdService;
import com.tanhua.vo.PageResult;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.CollectionUtils;

import java.sql.Time;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class PublishApiImpl implements PublishApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    @Override
    public String saveMovements(Publish publish) {
//        1、保存到publish表中
//        需要给publish赋值  id  pid  created
        publish.setId(new ObjectId()); //就是MongoDB表的主键
        publish.setPid(idService.getNextId("quanzi_pulish"));  // pid要求是一个long类型，这个数据是大数据做推送时要求的
        publish.setCreated(new Date().getTime()); // 创建时间 要求是Long类型 为了方便排序
        mongoTemplate.save(publish);
//        2、查询当前登录人的朋友
//        根据当前登录人查询朋友 tanhua_users
        Query query = new Query(Criteria.where("userId").is(publish.getUserId()));
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        if(!CollectionUtils.isEmpty(friendList)){
 //        3、保存到当前登录人朋友的时间线表中
//            有几个朋友就应该向几个朋友的时间线表quanzi_time_line中插入数据
            for (Friend friend : friendList) {
                TimeLine timeLine = new TimeLine();
                timeLine.setCreated(new Date().getTime());
                timeLine.setId(new ObjectId());
                timeLine.setPublishId(publish.getId());
                timeLine.setUserId(publish.getUserId());
                mongoTemplate.save(timeLine,"quanzi_time_line_"+friend.getFriendId());
            }
        }
//        4、向自己的时间线表中插入数据
        Album album = new Album();
        album.setCreated(new Date().getTime());
        album.setId(new ObjectId());
        album.setPublishId(publish.getId());
        mongoTemplate.save(album,"quanzi_album_"+publish.getUserId());

        return publish.getId().toString();
    }

    @Override   //查询当前登录人好友的动态
    public PageResult queryFriendMovements(Integer page, Integer pagesize, Long userId) {
        Query query = new Query();
//        根据时间需要排序
        query.with(PageRequest.of(page-1,pagesize,Sort.by(Sort.Direction.DESC,"created")));
//        query.skip((page-1)*pagesize).limit(pagesize);
        List<TimeLine> timeLines = mongoTemplate.find(query, TimeLine.class, "quanzi_time_line_" + userId);
        long count = mongoTemplate.count(query, TimeLine.class, "quanzi_time_line_" + userId);


        List<Publish> publishList = new ArrayList<>();
        for (TimeLine timeLine : timeLines) {
            Publish publish = mongoTemplate.findById(timeLine.getPublishId(), Publish.class);
//            但是因为目前用的都是测试数据，测试数据比较乱，所以有可能查不到这个publish
            if(publish==null){
                continue;
            }
            publishList.add(publish);
        }

        return new PageResult(page,pagesize,(int)count,publishList);
    }

    @Override  // 推荐给当前登录人的圈子
    public PageResult queryRecommendMovements(Integer page, Integer pagesize, Long userId) {
        Query query = new Query(Criteria.where("userId").is(userId));
//        根据时间需要排序
        query.with(PageRequest.of(page-1,pagesize,Sort.by(Sort.Direction.DESC,"score")));
        List<RecommendQuanzi> recommendQuanziList = mongoTemplate.find(query, RecommendQuanzi.class, "recommend_quanzi");
        long count = mongoTemplate.count(query, RecommendQuanzi.class, "recommend_quanzi");

        List<Publish> publishList = new ArrayList<>();
        for (RecommendQuanzi recommendQuanzi : recommendQuanziList) {
            Publish publish = mongoTemplate.findById(recommendQuanzi.getPublishId(), Publish.class);
//            但是因为目前用的都是测试数据，测试数据比较乱，所以有可能查不到这个publish
            if(publish==null){
                continue;
            }
            publishList.add(publish);
        }

        return new PageResult(page,pagesize,(int)count,publishList);
    }

    @Override // 查询自己发表的圈子动态
    public PageResult queryMySelfMovements(Integer page, Integer pagesize, Long userId) {
        Query query = new Query();
//        根据时间需要排序
        query.with(PageRequest.of(page-1,pagesize,Sort.by(Sort.Direction.DESC,"created")));
//        query.skip((page-1)*pagesize).limit(pagesize);
        List<Album> albumList = mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);
        long count = mongoTemplate.count(query, Album.class, "quanzi_album_" + userId);


        List<Publish> publishList = new ArrayList<>();
        for (Album album : albumList) {
            Publish publish = mongoTemplate.findById(album.getPublishId(), Publish.class);
//            但是因为目前用的都是测试数据，测试数据比较乱，所以有可能查不到这个publish
            if(publish==null){
                continue;
            }
            publishList.add(publish);
        }

        return new PageResult(page,pagesize,(int)count,publishList);
    }

    @Override
    public Publish findById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId),Publish.class);
    }

    @Override
    public PageResult queryPublishByUserId(Integer page, Integer pagesize, Long userId, Integer state) {
//        userId有可能为空    state也有可能为空
        Query query = new Query();
        Criteria criteria = new Criteria();
        if(userId!=null){
            criteria.and("userId").is(userId);
        }
        if(state!=null){
            criteria.and("state").is(state);
        }
        query.addCriteria(criteria);
        query.with(PageRequest.of(page-1,pagesize));

        List<Publish> publishList = mongoTemplate.find(query, Publish.class);
        long count = mongoTemplate.count(query, Publish.class);
        return new PageResult(page,pagesize,(int)count,publishList);
    }

    @Override
    public void updatePublishState(String publishId, int state) {
//        update quanzi_publish set state=? where publishId=?
        Query query = new Query(Criteria.where("id").is(new ObjectId(publishId)));
        Update update = new Update();
        update.set("state",state);
        mongoTemplate.updateFirst(query,update,Publish.class) ;

    }

    @Override
    public Publish findByPid(long pid) {
        Query query = new Query(Criteria.where("pid").is(pid));
        return mongoTemplate.findOne(query,Publish.class);
    }
}
